﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;
using System.Diagnostics;
namespace ZhaoKangWPFUserControl
{
    /// <summary>
    /// UserControl1.xaml 的交互逻辑
    /// </summary>
    public partial class TextBoxHex : UserControl
    {
        private int cnt = 0;
        public TextBoxHex()
        {
            InitializeComponent();
        }

        private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            int hexNumber;
            e.Handled = !int.TryParse(e.Text, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out hexNumber);
        }



        /*public string Text
        {
            get {
                 
                return (string)GetValue(TextProperty);
            }
            set {
                 
                SetValue(TextProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(TextBoxHex), new PropertyMetadata("", OnTextChanged));

        private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var cntrl = (TextBoxHex)o;
            cntrl.txbox.Text = (string)e.NewValue;
            cntrl.HexValue = UInt64.Parse((string)e.NewValue);
        }*/



        public UInt64? HexValue
        {
            get { return (UInt64?)GetValue(HexValueProperty); }
            set { SetValue(HexValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HexValueProperty =
            DependencyProperty.Register("HexValue", typeof(UInt64?), typeof(TextBoxHex), new PropertyMetadata((UInt64?)null, OnHexValueChanged));

        private static void OnHexValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var cntrl = (TextBoxHex)o;
            if (((UInt64?)(e.NewValue)).HasValue)
                cntrl.txbox.Text = ((UInt64?)(e.NewValue)).Value.ToString("X");
            else
                cntrl.txbox.Text = "";

        }






        //public string Text
        //{
        //    get { return txbox.Text; }
        //    set { txbox.Text = value; }
        //}

        private void UserControl_GotFocus_1(object sender, RoutedEventArgs e)
        {
            e.Handled = false;
            txbox.Focus();
            Trace.WriteLine($"{cnt++}: (Focus)txbox.CaretIndex = {txbox.CaretIndex}");
        }

        private void OnPreviewKeyDown(object sender, KeyEventArgs e)
        {
            //KeyConverter converter = new KeyConverter();
            //int hexNumber;
            if (e.Key == Key.Space)
                e.Handled = true;
            Trace.WriteLine($"{cnt++}: (OnPreviewKeyDown)txbox.CaretIndex = {txbox.CaretIndex}");
        }

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            //TextBox txtbox = (TextBox)sender;
            txbox.Text = GetNumberFromString(txbox.Text);
            if (txbox.Text == "")
                HexValue = null;
            else
                HexValue = UInt64.Parse(txbox.Text,NumberStyles.HexNumber);
            //txbox.CaretIndex = txbox.Text.Length;
            //Trace.WriteLine($"{cnt++}: (OnTextChanged)txbox.CaretIndex = {txbox.CaretIndex}");
        }

        /// <summary>
        /// Strips non-numerical characters from input string
        /// </summary>
        /// <param name="str">input string</param>
        /// <returns>numerical string or empty string</returns>
        private static string GetNumberFromString(string str)
        {
            StringBuilder numberBuilder = new StringBuilder();
            foreach (char c in str)
            {
                if (char.IsNumber(c) || (c >= 'a' && c<='f')||(c>='A'&&c<='F'))
                {   
                    numberBuilder.Append(c);
                }
            }
            return numberBuilder.ToString();
        }

 

        private void OnPreviewKeyUp(object sender, KeyEventArgs e)
        {
            //Trace.WriteLine($"kkkkk txbox.CaretIndex = {txbox.CaretIndex}");
            txbox.CaretIndex = txbox.Text.Length;
        }
    }
}
